/**
 * Copyright 2015 Qiyi Inc. All rights reserved.
 *
 * @file:   Stream.Util.js
 * @path:   js-src/Stream/
 * @desc:
 * @author: jiegang@qiyi.com
 * @date:   2015-01-10
 */
qui(function (require, exports, module) {


    Stream.Util = $.extend(true, {}, Ancestor.Util, {

        // jqGrid 相关回调函数
        formatter: {

            streamName: function (v, r) {
                if (r.encodeType) {
                    //return '<a href="' + r.streamAddress + '" target="_blank">' + r.streamName + '</a>';
                    return '<a href="' + r.streamUrls + '" target="_blank">' + r.streamName + '</a>';
                } else {
                    //return '<a href="http://www.cutv.com/demo/live_test.swf?url=rtmp://' + r.streamIp + '/live/' + r.streamName + '" target="_blank">' + r.streamName + '</a>';
                    return '<a href="http://www.cutv.com/demo/live_test.swf?url=' + r.streamUrls + '" target="_blank">' + r.streamName + '</a>';
                }
            },

            streamIp: function (v, r) {
                var port = r.port || '8080';
                return '<a href="http://' + r.internalIp + ':' + port + '/stat" target="_blank">' + r.streamIp + '</a>';
            },

            encodedIp: function (v, r) {
                // return '<a href="http://' + r.encodedIp + '" target="_blank">' + r.encodedIp + '</a>';
                return '<a href="http://encoder.live.video.qiyi.domain/agent?ip=' + r.encodedIp + '" target="_blank">' + r.encodedIp + '</a>';
            },

            inputSignal: function (v, r) {
                var inputSignal = r.inputSignal;
                if (typeof inputSignal === 'undefined') {
                    return '';
                }

                if (inputSignal.split(':')[0] === 'rtmp') {
                    return '<a href="http://www.cutv.com/demo/live_test.swf?url=' + inputSignal + '" target="_blank">' + inputSignal + '</a>';
                } else {
                    return inputSignal;
                }
            },

            dolbySignal: function (v, r) {
                return '<a href="' + r.dolbyStreamUrls + '" target="_blank">' + r.dolbyStreamUrl + '</a>';
                //return r.dolbyStreamUrl;
            },

            dest: function (v, r) {
                return Stream.Config.DEST[r.dest];
            },

            status: function (v, r) {
                return Stream.Config.STATUS[r.status];
            },

            streamType: function (v, r) {
                return Stream.Config.TYPE[r.streamType];
            },

            isEnable: function (v, r) {
                return r.isEnable === '1' ? '上线' : '下线';
            },

            encodeType: function (v, r) {
                return r.encodeType == 0 ? 'H264' : 'H265';
            },

            create: function (v, r) {
                var optionsObj = {},
                    flvOptionsObj = {},
                    encoderOptionsObj = {};

                optionsObj.id = r.id;
                optionsObj.fatherId = r.fatherId;
                optionsObj.channelName = r.channelName;
                optionsObj.streamName = r.streamName;
                optionsObj.streamIp = r.streamIp;
                optionsObj.internalIp = r.internalIp;
                optionsObj.isDefault = 0;
                optionsObj.streamType = r.streamType;
                optionsObj.dolbyStreamName = r.dolbyStreamName;
                optionsObj.dolbyStreamUrl = r.dolbyStreamUrl;
                optionsObj.encodeType = r.encodeType;
                optionsObj.streamAddress = r.streamAddress;
                options = encodeURIComponent(JSON.stringify(optionsObj));

                flvOptionsObj = optionsObj;
                flvOptionsObj.isDefault = 1;
                flvOptions = encodeURIComponent(JSON.stringify(flvOptionsObj));

                encoderOptionsObj = optionsObj;
                encoderOptionsObj.dest = r.dest;
                encoderOptionsObj.destName = Stream.Config.DEST[r.dest];
                encoderOptionsObj.liveType = Ancestor.Util.getUrlId('livetype');
                encoderOptions = encodeURIComponent(JSON.stringify(encoderOptionsObj));

                var htmls = [];
                htmls.push('<div class="oper" data-id="">');
                if (encoderOptionsObj.liveType == Stream.Config.ENCODER_CONFIG.liveType_lb) {
                    htmls.push('<a href="javascript:;" data=' + encoderOptions + ' type="encoder" onclick="Stream.Util.saveStreamShow(this);">编码</a>');
                }

                // 0 = H264, 1 = H265
                if (r.encodeType == "1") {
                    htmls.push('<a href="javascript:;" data=' + options + ' type="newts" onclick="Stream.Util.saveStreamShow(this);">TS</a>');
                } else {
                    htmls.push('<a href="javascript:;" data=' + flvOptions + ' type="flv" onclick="Stream.Util.saveStreamShow(this);">FLV</a>');
                    htmls.push('<a href="javascript:;" data=' + options + ' type="ts" onclick="Stream.Util.saveStreamShow(this);">TS</a>');
                    if (r.dolbyStreamUrl != '') {
                        htmls.push('<a href="javascript:;" data=' + options + ' type="dolby" onclick="Stream.Util.saveStreamShow(this);">DOLBY</a>');
                    }
                }

                //htmls.push('<a href="javascript:;" data='+options+' type="p2p" onclick="Stream.Util.saveStreamShow(this);">P2P</a>');
                htmls.push('</div>');

                return htmls.join('');
            },

            operate: function (v, r) {

                var obj = {};
                obj.id = r.id;
                obj.fatherId = r.fatherId;
                obj.channelName = r.channelName;
                obj.streamName = r.streamName;
                obj.streamIp = r.streamIp;
                obj.streamType = r.streamType;
                obj.peerCount = r.peerCount;
                obj.bcsNum = r.bcsNum;
                obj.cutterIdFlv = r.cutterIdFlv;
                obj.cutterIdTs = r.cutterIdTs;
                obj.status = r.status;
                obj.isEnable = r.isEnable;
                obj.inputBits = r.inputBits;
                obj.outputBits = r.outputBits;
                obj.bitRate = r.bitRate;
                obj.aspectRatio = r.aspectRatio;
                obj.screenSize = r.screenSize;
                obj.liveType = Ancestor.Util.getUrlId('livetype');
                obj.dest = r.dest;
                obj.internalIp = r.internalIp;
                obj.streamApiVersion = r.streamApiVersion;
                obj.dolbyStreamName = r.dolbyStreamName;
                obj.dolbyStreamUrl = r.dolbyStreamUrl;
                obj.dolbyAudioChannel = r.dolbyAudioChannel;
                obj.encodeType = r.encodeType;
                obj.streamAddress = r.streamAddress;
                obj.playType = r.playType;
                obj.backupEachOther = r.backupEachOther;

                var str = encodeURIComponent(JSON.stringify(obj));

                var htmls = [];
                htmls.push('<div class="oper" data-id="">');
                htmls.push('<a href="javascript:;" data=' + str + ' onclick="Stream.Util.modifyStream(this);">修改</a>');
                htmls.push('<a href="javascript:;" data=' + str + ' onclick="Stream.Util.deleteStream(this);">删除</a>');
                htmls.push('</div>');

                return htmls.join('');
            }
        },

        // 直播流事件绑定
        bindStreamEvent: function () {

        },

        // 保存流
        saveStreamShow: function (obj) {
            var options = JSON.parse(decodeURIComponent($(obj).attr('data')))
            options.type = $(obj).attr('type');

            var self = this;

            Stream.Dao.getStreamInfo({
                fatherId: options.fatherId,
                streamName: options.streamName
                //formatType : options.type
            }, function (json) {

                if (json.code == 'A00000') {

                    options.flv = null;
                    options.hcdn = null;
                    options.hcdnlive = null;
                    options.hasCreate = null;
                    options.status = null;

                    options.ts = null;
                    options.mp4 = null;
                    options.p2p = null;

                    options.dolby = null;
                    options.newts = null;

                    $.each(json.data, function () {

                        if (this.formatType == 'FLV') {
                            options.flv = this.url;
                            options.flvDelay = this.sliceDelay;
                            options.flvDelayS = this.delayS;
                            options.flvDelayE = this.delayE;

                            if (options.type == 'flv') {
                                options.status = this.status;
                                options.hasCreate = 1;
                                options.isDefault = this.isDefault;
                            }

                        }

                        if (this.formatType == 'HCDN') {
                            options.hcdn = this.url;
                            options.hcdnDelay = this.sliceDelay;
                            options.hcdnDelayS = this.delayS;
                            options.hcdnDelayE = this.delayE;
                        }

                        if (this.formatType == "HLFLV") {
                            options.hcdnlive = this.url;
                        }

                        if (this.formatType == 'TS') {
                            if (options.type == 'ts') {
                                options.ts = this.url;
                                options.tsUrl = Stream.Util.decodeVRSData(this.formatType, options.streamType);
                                options.status = this.status;
                                options.hasCreate = 1;
                            }

                            if (options.type == "newts") {
                                options.newts = this.url;
                                options.newtsCh = this.dolbyCh;
                                options.status = this.status;
                                options.hasCreate = 1;
                            }
                        }


                        if (this.formatType == 'MP4') {
                            options.mp4 = this.url;
                        }

                        if (this.formatType == 'P2P') {
                            options.p2p = this.url;
                            if (options.type == 'p2p') {
                                options.status = this.status;
                                options.hasCreate = 1;
                            }

                        }

                        if (this.formatType == 'DOLBY') {
                            options.dolby = this.url;
                            options.dolbyCh = this.dolbyCh;
                            if (options.type == 'dolby') {
                                options.status = this.status;
                                options.hasCreate = 1;
                            }
                        }

                    });

                    //options.liveStream = json.data;

                    //console.log(options);
                    if (options.type == 'encoder') {
                        var request = {};
                        request.url = Stream.Config.ENCODER_CONFIG.encoder_state;
                        request.type = 'get';

                        request.params = {
                            channelid: options.fatherId,
                            obj: 'rtmp://' + options.internalIp + '/live/' + options.streamName
                        };
                        request = JSON.stringify(request);

                        //$(document).tips({
                        //    content: "操作中...",
                        //    type: "loading"
                        //});

                        Stream.Dao.encoderOperation({
                            request: request
                        }, function (json) {
                            if (typeof(json) == "undefined") {
                                options.encoderState = "无法获取编码状态!";
                                options.status = 2;
                            } else if (json.error_code == '0') {
                                options.encoderState = "编码中...";
                                options.status = 0;
                            } else {
                                options.encoderState = "未编码";
                                options.status = 1;
                            }


                            $('.ui-tips-close').trigger('click');
                            self.fetchSpanInfos(options, obj);
                        });
                    } else {
                        self.fetchSpanInfos(options, obj);
                    }

                } else {
                    if (json.msg == undefined) {
                        msg = Stream.Config.REQUEST_FAIL;
                    } else {
                        msg = json.msg;
                    }

                    $(document).tips({
                        content: msg,
                        type: "error"
                    });
                }
            });

        },

        fetchSpanInfos: function (options, obj) {
            var self = this;
            var actionNext = function () {
                $(document).dequeue("fetchSpans");
            };

            var actions = [];

            if (options.type == 'flv') {
                actions.push(function () {
                    self.fetchSpanInfo(options, 'flv', actionNext)
                });
            } else if (options.type == 'ts') {
                actions.push(function () {
                    self.fetchSpanInfo(options, 'ts', actionNext)
                });
            } else if (options.type == 'newts') {
                actions.push(function () {
                    self.fetchSpanInfo(options, 'newts', actionNext)
                });
            } else if (options.type == 'dolby') {
                actions.push(function () {
                    self.fetchSpanInfo(options, 'dolby', actionNext);
                });
            }

            actions.push(function () {
                self.openStreamDlg(options, obj);
                actionNext()
            });

            $(document).queue("fetchSpans", actions);
            actionNext();

        },

        fetchSpanInfo: function (options, type, callback) {
            var self = this;
            var request = {};
            self.options = options;
            self.callback = callback;
            request.type = 'get';
            if (type == 'newts') {
                request.url = Stream.Config.STREAM_SPAN[type].replace("{channelName}", options['newtsCh']);
            } else if (type == 'dolby') {
                request.url = Stream.Config.STREAM_SPAN[type].replace("{channelName}", options['dolbyCh']);
            } else {
                request.url = Stream.Config.STREAM_SPAN[type].replace("{channelName}", options[type]);
            }
            request = JSON.stringify(request);

            Ancestor.Dao.redirectRequest({request: request}, function (json) {
                if (json.status == '1') {
                    var jsonData = json.data;
                    if (self.options.type == 'flv') {
                        self.options.flvSpan = jsonData.span;
                        self.options.streamServer = jsonData.stream_server;
                        self.options.streamIndex = jsonData.stream_server.trim().split("=")[1];
                        self.options.streamUrl = jsonData.stream_url.trim().split(" ");
                    } else if (self.options.type == 'ts') {
                        self.options.tsSpan = jsonData.span;
                        self.options.streamServer = jsonData.stream_server;
                        self.options.streamIndex = jsonData.stream_server.trim().split("=")[1];
                        self.options.streamUrl = jsonData.stream_url.trim().split(" ");
                    } else if (self.options.type == 'newts') {
                        self.options.newtsSpan = jsonData.span;
                    } else if (self.options.type == 'dolby') {
                        self.options.dolbySpan = jsonData.span;
                        self.options.streamServer = jsonData.stream_server;
                        self.options.streamIndex = jsonData.stream_server.trim().split("=")[1];
                        self.options.streamUrl = jsonData.stream_url.trim().split(" ");
                    }
                } else {
                    if (self.options.type == 'flv') {
                        self.options.flvSpan = -1;
                    } else if (self.options.type == 'ts') {
                        self.options.tsSpan = -1;
                    } else if (self.options.type == 'newts') {
                        self.options.newtsSpan = -1;
                    } else if (self.options.type == 'dolby') {
                        self.options.dolbySpan = -1;
                    }
                }
                self.callback();
            });
        },

        // 打开保存对话框
        openStreamDlg: function (options, a_tag) {
            var self = this;
            var $container = $("#stream-save-dlg");
            if (options.type != 'encoder') {
                var dlgTitle = '直播流创建';
            } else {
                var dlgTitle = '直播流编码';
            }

            $container.dialog({
                title: dlgTitle,
                appendTo: null,
                modal: true,
                width: 440,
                position: ['top', 'top+20'],

                open: function () {
                    $(".ui-dialog-titlebar-close").html('<span class="ui-button-icon-primary ui-icon ui-icon-closethick"></span><span class="ui-button-text">close</span>');

                },
                close: function () {

                }
            });

            var $tmpl = $("#save-stream");
            $container.html($tmpl.tmpl(options));

            if (options.type == "encoder") {
                self.bindEncoderBtn(a_tag);
            } else {
                self.bindStreamInfoBtn(a_tag);
            }
        },

        bindEncoderBtn: function (a_tag) {
            $(".btn-stream").unbind("click").bind('click', function () {

                $(this).attr('disabled', 'disabled');

                var type = $(this).attr('operate-type');
                var params = getParam($(".stream-info"));
                var self = $(this);

                var request = {};

                if (type == 'start') {
                    request.url = Stream.Config.ENCODER_CONFIG.encoder_start;

                    if (params.internalIp == '') {
                        $(document).tips({
                            content: "RTMP服务器IP填写错误, 无法找到内网地址",
                            type: "error"
                        });

                        self.removeAttr('disabled');
                        return;
                    }

                    request.params = {
                        channelid: params.fatherId,
                        encoder: 'null',
                        stream_type: Stream.Config.STREAM_TYPE_INFO[params.streamType][0],
                        //obj: 'rtmp://' + params.streamIp + '/live/' + params.streamName,
                        obj: 'rtmp://' + params.internalIp + '/live/' + params.streamName,
                        dest: params.dest
                    };

                    if (typeof(params.dest) == 'undefined' || params.dest == '') {
                        $(document).tips({
                            content: "未设置地区，无法启动流。",
                            type: "error"
                        });

                        self.removeAttr('disabled');

                        return;
                    }
                } else if (type == 'stop') {
                    request.url = Stream.Config.ENCODER_CONFIG.encoder_close;
                    request.params = {
                        channelid: params.fatherId,
                        obj: 'rtmp://' + params.internalIp + '/live/' + params.streamName
                    };
                } else {
                    $(document).tips({
                        content: "操作失败...",
                        type: "error"
                    });

                    self.removeAttr('disabled');
                    return;
                }

                request.type = 'get';
                request = JSON.stringify(request);

                //$(document).tips({
                //    content: "操作中...",
                //    type: "loading"
                //});

                Stream.Dao.encoderOperation({
                    request: request
                }, function (json) {
                    if (typeof(json) != "undefined" && json.error_code == '0') {
                        $('.ui-tips-close').trigger('click');

                        $("#stream-save-dlg").dialog('close');
                        $(a_tag).trigger("click");

                        $(document).tips({
                            content: "操作成功...",
                            type: "success"
                        });


                        // 刷新页面
                        setTimeout("location.reload()", 2000);

                    } else {
                        $(document).tips({
                            content: "操作失败...",
                            type: "error"
                        });

                        self.removeAttr('disabled');
                    }
                });
            });
        },

        bindStreamInfoBtn: function (a_tag) {
            $(".btn-stream").unbind("click").bind('click', function () {
                var type = $(this).attr('operate-type');
                var params = getParam($(".stream-info"));

                if (params.type == 'p2p') {
                    if (type == 'start')
                        type = 'online';
                    else
                        type = 'offline';
                }

                data = {};
                data.api = params.type + '/' + type;
                data.data = params;

                $(document).tips({
                    content: "页面提交中",
                    type: "loading"
                });

                Stream.Dao.streamInfoOperate(data, function (json) {

                    if (json.code == 'A00000') {
                        /*
                         $(document).tips({
                         content: "操作成功",
                         type: "close"
                         });
                         */

                        $('.ui-tips-close').trigger('click');

                        $("#stream-save-dlg").dialog('close');
                        $(a_tag).trigger("click");

                    } else {
                        var msg = Stream.Config.REQUEST_FAIL;
                        if (json.msg != undefined)
                            msg = json.msg;

                        $(document).tips({
                            content: msg,
                            type: "error"
                        });

                    }

                });

            });
        },

        modifyStream: function (obj) {

            var self = this;
            var options = JSON.parse(decodeURIComponent($(obj).attr('data')));
            //console.log(options);
            var sg = Stream.Action.getStreamGrid();


            Stream.Dao.getStreamInfo({
                fatherId: options.fatherId,
                streamName: options.streamName
                //formatType : options.type
            }, function (json) {

                options.streamApiVersionEditable = true;
                if (json.code == 'A00000' && json.data.length > 0) {
                    options.streamApiVersionEditable = false;
                    options.streamApiVersionLabel = Stream.Config.STREAM_API_VERSION[options.streamApiVersion];
                }

                sg.addStreamShow({
                    title: '码流修改',
                    callback: "onModifyStream"
                });

                var $tmpl = $("#add-stream");
                options.streamTypeSlt = options.streamType;
                options.streamType = Stream.Config.TYPE;
                options.cutterIdsFlv = Stream.Config.CUTTER_ID.FLV;
                options.cutterIdsTs = Stream.Config.CUTTER_ID.TS;
                options.destVal = options.dest;
                options.dest = Stream.Config.DEST;
                options.operate = "modify";
                options.cutterIdFlv = options.cutterIdFlv + '';
                options.cutterIdTs = options.cutterIdTs + '';

                options.carouselDefaultStream = options.streamType;
                options.universalCode = Ancestor.Util.getUrlId('universalcode');

                Stream.Config.BEFORE_DATA = options;
                sg.dlg.html($tmpl.tmpl(options));

                self.setStreamTypeTip(options.streamTypeSlt);

                if (options.encodeType == 1) {
                    $("#streamIpDiv").hide();
                    $("#streamAddressDiv").show();
                } else {
                    $("#streamIpDiv").show();
                    $("#streamAddressDiv").hide();
                }
            });

        },

        deleteStream: function (obj) {

            var options = JSON.parse(decodeURIComponent($(obj).attr('data')));

            var tmp = {};

            tmp.id = options.id;
            tmp.fatherId = options.fatherId;
            tmp.streamName = options.streamName;

            if (options.status == 1) {
                $(document).tips({
                    content: tmp.streamName + '在编码中,请停止后再删除！',
                    type: "error"
                });
                return;
            }

            var sg = Stream.Action.getStreamGrid();

            sg.onDelStream(tmp);
        },


        streamNameCreateSuggest: function (el, options) {
            options = $.extend(true, {
                // 是否自动选择地一条
                autoFocus: true,
                // 选中input时请求
                focusSearch: false,
                sortBy: false,
                // 是否校验结果
                validate: false,
                // 多条时是否验证必有数据
                multipleValid: false,
                // 是否高亮
                highlight: true,
                // 是否onblur时清空无效结果
                clearInvalid: true,
                noResult: '对不起，没有这个结果',
                valueKey: 'id',
                parseValue: function () {
                    var val = this.element.val();
                    var ret = [];
                    if (val) {
                        var items = val.split(';');
                        $.each(items, function (i, item) {
                            item = item.split(',');
                            ret.push({
                                value: item[1],
                                id: item[0],
                                label: item[1]
                            });
                        });
                    }
                    this._value('');
                    return ret;
                },
                create: function (event, ui) {
                    $(this).autocomplete('init');

                    if (options.focusSearch) {
                        $(el).on('focus', function () {
                            if ($.trim(this.value) !== '') {
                                $(this).autocomplete('search');
                            }
                        });
                    }
                },
                otherParam: $.extend({}, options.params),
                source: function (request, response) {
                    var self = this;
                    var term = $.trim(request.term);
                    var result = [];
                    if (!term) {
                        return null;
                    }
                    self.getResultData = function () {
                        return result;
                    };
                    var options = this.options;
                    var dataProcess = options.process || process;
                    var param = {};
                    if (!options.ignoreWord) {
                        //传递 word  term
                        param = {
                            word: term
                        };
                    }
                    param = $.extend(true, options.otherParam, param);

                    //根据dom上定义的sugg-filter过滤项增加过滤参数
                    //sugg-filter中的过滤项以逗号分隔
                    var filterStr = $(el).attr('sugg-filter');
                    if ($.trim(filterStr)) {
                        var filters = $.trim(filterStr).split(',');
                        if (filters && filters.length > 0) {
                            for (var i = 0, l = filters.length, filter; i < l; i++) {
                                filter = filters[i].split('=');
                                if (filter.length == 2) {
                                    param[filter[0]] = filter[1];
                                }
                            }
                        }
                    }

                    var url = options.url;

                    var encodeType = $('#encodeType').val();
                    if (encodeType == "1") {
                        url = "/api/suggest/h265streamName"
                    } else {
                        url = "/api/suggest/streamName"
                    }

                    var getParam = options.getParam;
                    if (getParam) {
                        if ($.isFunction(options.getParam)) {
                            param = $.extend(true, param, getParam.call(this, term));
                        } else if ($.isPlainObject(getParam)) {
                            param = $.extend(true, param, getParam);
                        }
                    }

                    param.fatherId = $(el).parents(".stream-add-form").find('[name="fatherId"]').val();

                    Stream.Dao.getStreamNameCodeData(url, param, function (json) {
                        var ret = dataProcess.call(self, json, term);
                        if ($.isArray(options.sortBy)) {
                            sortBy.apply(self, [ret].concat(options.sortBy));
                        } else if ($.isFunction(options.onSortBy)) {
                            options.onSortBy.apply(self, [ret, term]);
                        }

                        if (options.highlight) {
                            if ($.isFunction(options.onHighlight)) {
                                options.onHighlight.apply(self, [ret, term]);
                            } else {
                                Stream.Util.highlight(ret, null, term);
                            }
                        }
                        result = ret;
                        if ($.isFunction(options.onLoad)) {
                            options.onLoad.apply(self, [result, term]);
                        }
                        response(result);
                    });

                }
            }, options);

            /* ui-front ui-suggest*/
            return $(el).wrap('<span class="ui-front ui-suggest" ></span>').autocomplete(
                options).on('autocompleteresponse', function (event, ui) {
                    var content = ui.content;
                    $(this).autocomplete('validate', content);
                }).on('autocompleteselect', function (event, ui) {
                    ui.item.value = ui.item.streamName;
                    return $(this).autocomplete('setValue', ui.item);

                }).on('autocompletesearch', function (event, ui) {
                    //支持多选
                    return $(this).autocomplete('multiplesearch');
                });
        },

        streamName: function (el, options) {

            var tpl = '<div><div class="contract-item">' +
                '<span class="contract-width200">${streamName}</span>' +
                '<span style="border-right:none;">${streamIp}</span>' +
                '</div></div>';

            var title = {
                streamName: '流名称',
                streamIp: 'RTMP IP/流地址'
            };

            var getHtmlByData = function (data) {
                var htmls = [];
                var htmlStr = $('<div></div>').html($(tpl).tmpl(data));
                return htmlStr.html();
            };
            var titleHtml = getHtmlByData(title);

            var suggestUrl = '/api/suggest/streamName';

            Stream.Util.streamNameCreateSuggest(el, $.extend(true, {

                url: suggestUrl,
                ignoreWord: true,
                header: titleHtml,
                validate: true,
                getParam: function (term) {
                    term = $.trim(term);
                    return {
                        'streamName': term
                    };
                },
                process: function (json) {
                    var encodeType = $('#encodeType').val();
                    if (json.data) {
                        var data = encodeType == "1" ? json.data : json.data.streamInfoList;

                        if (json.data.liveType == 1)
                            $('#streamIp').attr('disabled', 'disabled');

                        if (!data) {
                            return [];
                        }
                        var ret = [];
                        $.map(data, function (item) {
                            ret.push($.extend(true, item, {
                                streamName: encodeType == "1" ? Stream.Util.makeDolbyStreamName(item.outputSignal) : item.streamName,
                                streamIp: encodeType == "1" ? item.outputSignal : item.streamIp
                            }));

                        });
                        return ret;
                    }
                    return [];
                },
                onHighlight: function (data, term) {
                    Stream.Util.highlight(data, 'dataName', term);
                },
                template: function (item) {
                    return getHtmlByData(item);
                }
            }, options)).parent().addClass('ui-qitan');
        },


        streamNameSuggest: function ($inputs, options) {

            $inputs.each(function (index, element) {
                var self = this;
                Stream.Util.streamName($(this), $.extend(true, {
                    validate: false,
                    select: function (e, data) {
                        $(self).parent().parent().find('span.hasConnectQitan').show();
                        var $input = $(e.currentTarget);
                        $input.data('value', data.item.code);

                        var encodeType = $('#encodeType').val();
                        if (encodeType == 1) {
                            $('#streamAddress').val(data.item.streamIp);
                        } else {
                            $('#streamIp').val(data.item.streamIp);
                        }
                        //console.log(data);
                    },
                    onNoResult: function () {
                        $(self).parent().parent().find('span.hasConnectQitan').hide();
                    },
                    change: function (event, ui) {
                        if (null === ui.item) {
                            $(self).parent().parent().find('span.hasConnectQitan').hide();
                        }
                    }
                }, options));
            });
        },


        dolbyStreamNameCreateSuggest: function (el, options) {
            options = $.extend(true, {
                // 是否自动选择地一条
                autoFocus: true,
                // 选中input时请求
                focusSearch: false,
                sortBy: false,
                // 是否校验结果
                validate: false,
                // 多条时是否验证必有数据
                multipleValid: false,
                // 是否高亮
                highlight: true,
                // 是否onblur时清空无效结果
                clearInvalid: true,
                noResult: '对不起，没有这个结果',
                valueKey: 'id',
                parseValue: function () {
                    var val = this.element.val();
                    var ret = [];
                    if (val) {
                        var items = val.split(';');
                        $.each(items, function (i, item) {
                            item = item.split(',');
                            ret.push({
                                value: item[1],
                                id: item[0],
                                label: item[1]
                            });
                        });
                    }
                    this._value('');
                    return ret;
                },
                create: function (event, ui) {
                    $(this).autocomplete('init');

                    if (options.focusSearch) {
                        $(el).on('focus', function () {
                            if ($.trim(this.value) !== '') {
                                $(this).autocomplete('search');
                            }
                        });
                    }
                },
                otherParam: $.extend({}, options.params),
                source: function (request, response) {
                    var self = this;
                    var term = $.trim(request.term);
                    var result = [];
                    if (!term) {
                        return null;
                    }
                    self.getResultData = function () {
                        return result;
                    };
                    var options = this.options;
                    var dataProcess = options.process || process;
                    var param = {};
                    if (!options.ignoreWord) {
                        //传递 word  term
                        param = {
                            word: term
                        };
                    }
                    param = $.extend(true, options.otherParam, param);

                    //根据dom上定义的sugg-filter过滤项增加过滤参数
                    //sugg-filter中的过滤项以逗号分隔
                    var filterStr = $(el).attr('sugg-filter');
                    if ($.trim(filterStr)) {
                        var filters = $.trim(filterStr).split(',');
                        if (filters && filters.length > 0) {
                            for (var i = 0, l = filters.length, filter; i < l; i++) {
                                filter = filters[i].split('=');
                                if (filter.length == 2) {
                                    param[filter[0]] = filter[1];
                                }
                            }
                        }
                    }

                    var url = options.url;
                    var getParam = options.getParam;
                    if (getParam) {
                        if ($.isFunction(options.getParam)) {
                            param = $.extend(true, param, getParam.call(this, term));
                        } else if ($.isPlainObject(getParam)) {
                            param = $.extend(true, param, getParam);
                        }
                    }

                    param.fatherId = $(el).parents(".stream-add-form").find('[name="fatherId"]').val();
                    param.encodeType = $('#encodeType').val();

                    Stream.Dao.getStreamNameCodeData(url, param, function (json) {
                        var ret = dataProcess.call(self, json, term);
                        if ($.isArray(options.sortBy)) {
                            sortBy.apply(self, [ret].concat(options.sortBy));
                        } else if ($.isFunction(options.onSortBy)) {
                            options.onSortBy.apply(self, [ret, term]);
                        }

                        if (options.highlight) {
                            if ($.isFunction(options.onHighlight)) {
                                options.onHighlight.apply(self, [ret, term]);
                            } else {
                                Stream.Util.highlight(ret, null, term);
                            }
                        }
                        result = ret;
                        if ($.isFunction(options.onLoad)) {
                            options.onLoad.apply(self, [result, term]);
                        }
                        response(result);
                    });

                }
            }, options);

            /* ui-front ui-suggest*/
            return $(el).wrap('<span class="ui-front ui-suggest" ></span>').autocomplete(
                options).on('autocompleteresponse', function (event, ui) {
                    var content = ui.content;
                    $(this).autocomplete('validate', content);
                }).on('autocompleteselect', function (event, ui) {
                    ui.item.value = ui.item.dolbyStreamName;
                    return $(this).autocomplete('setValue', ui.item);

                }).on('autocompletesearch', function (event, ui) {
                    //支持多选
                    return $(this).autocomplete('multiplesearch');
                });
        },

        dolbyStreamName: function (el, options) {

            var tpl = '<div><div class="contract-item" style="width: 800px;">' +
                '<span class="contract-width200">${dolbyStreamName}</span>' +
                '<span style="border-right:none;">${dolbyStreamUrl}</span>' +
                '</div></div>';

            var title = {
                dolbyStreamName: '流名称',
                dolbyStreamUrl: '流地址'
            };

            var getHtmlByData = function (data) {
                var htmls = [];
                var htmlStr = $('<div></div>').html($(tpl).tmpl(data));
                return htmlStr.html();
            };
            var titleHtml = getHtmlByData(title);

            Stream.Util.dolbyStreamNameCreateSuggest(el, $.extend(true, {

                url: '/api/suggest/dubistreamName',
                ignoreWord: true,
                header: titleHtml,
                validate: true,
                getParam: function (term) {
                    term = $.trim(term);
                    return {
                        'streamName': term
                    };
                },
                process: function (json) {
                    if (json.data) {
                        var data = json.data;

                        if (!data) {
                            return [];
                        }
                        var ret = [];
                        $.map(data, function (item) {
                            ret.push($.extend(true, item, {
                                dolbyStreamName: Stream.Util.makeDolbyStreamName(item.outputSignal),
                                dolbyStreamUrl: item.outputSignal,
                                dolbyAudio: item.audio || ''
                            }));

                        });
                        return ret;
                    }
                    return [];
                },
                onHighlight: function (data, term) {
                    Stream.Util.highlight(data, 'dataName', term);
                },
                template: function (item) {
                    return getHtmlByData(item);
                }
            }, options)).parent().addClass('ui-qitan');
        },

        makeDolbyStreamName: function (streamUrl) {
            var datas = streamUrl.split('/');
            return datas[datas.length - 1];
        },

        dolbyStreamNameSuggest: function ($inputs, options) {
            $inputs.each(function (index, element) {
                var self = this;
                Stream.Util.dolbyStreamName($(this), $.extend(true, {
                    validate: false,
                    select: function (e, data) {
                        $(self).parent().parent().find('span.hasConnectQitan').show();
                        var $input = $(e.currentTarget);
                        $input.data('value', data.item.dolbyStreamName);
                        $('#dolbyStreamUrl').val(data.item.dolbyStreamUrl);
                        if (data.item.dolbyAudio == "copy") {
                            $('select[name=dolbyAudioChannel]').val("ATMOS");
                        } else {
                            $('select[name=dolbyAudioChannel]').val("5.1");
                        }
                        //console.log(data);
                    },
                    onNoResult: function () {
                        $(self).parent().parent().find('span.hasConnectQitan').hide();
                    },
                    change: function (event, ui) {
                        if (null === ui.item) {
                            $(self).parent().parent().find('span.hasConnectQitan').hide();
                        }
                    }
                }, options));
            });
        },

        setStreamTypeTip: function (val) {
            var info = Stream.Config.STREAM_TYPE_INFO[val];

            $('#streamTypeTip').html('分辨率： ' + info[1] + ' 视频码率：' + info[2] + ' 音频码率：' + info[3]);
        },

        highlight: function (data, key, term) {
            data.forEach(function (item, i) {
                key = key || 'label';
                var label = item[key];
                if (!label || !term) {
                    return;
                }
                item[key] = (item[key] + '').replace(new RegExp('(' + term + ')', 'i'), '<b>$1</b>');
                // 高亮未输入部分
                // if (label.toLowerCase().indexOf(term.toLowerCase()) == 0) {
                //     item[key] = item[key].substr(0, term.length)
                //                   + '<b>'
                //                   + item[key].substr(term.length) + '</b>';
                // }
            });
        },
        decodeVRSData: function (formatType, streamType) {
            var vrsData = Stream.Config.VRS_DATA;
            var retValue = "";
            if (vrsData == null) {
                return retValue;
            }
            try {
                $.each(vrsData.streams, function (i, element) {
                    if (element.steamType == streamType.toUpperCase() && element.formatType == formatType.toUpperCase()) {
                        retValue = element.url;
                        return false;
                    }
                })
            } catch (e) {
                console.log("error", e);
            }
            return retValue;
        },

        encodeTypeSwitch: function ($container) {
            $container.find("select[name=encodeType]").bind("change", function (e) {
                var $curTarget = $(e.currentTarget);
                var streamIpDiv = $container.find("#streamIpDiv");
                var streamAddressDiv = $container.find("#streamAddressDiv");
                if ($curTarget.val() == 0) {
                    streamIpDiv.show();
                    streamAddressDiv.hide();
                } else if ($curTarget.val() == 1) {
                    streamIpDiv.hide();
                    streamAddressDiv.show();
                }
            });
            $container.find("select[name=encodeType]").change();
        },
        doVRSQuery: function (callback) {
            if (Stream.Config.CHANNEL_INFO != null) {
                var queryUrl = null;
                if (Stream.Config.CHANNEL_INFO.status == "FREE") {
                    Stream.Util.doVRSFreeQueryFirst(callback);
                } else {
                    Stream.Util.doVRSVipQuery(callback);
                }
            } else {
                callback()
            }
        },

        buildVRSFreeUrl: function (qipuId, platSrc) {
            var baseUrl = Stream.Config.VRS_CONFIG.BASE_FREE_URL;
            var params = [];
            params.push({key: "lc", value: "" + qipuId})
            params.push({key: "src", value: "" + platSrc})
            params.push({key: "v", value: "1"})
            params.push({key: "uid", value: "1351697526" })
            params.push({key: "t", value: "" + (Date.now() % 100) })
            params.push({key: "k_err_retries", value: "0" })
            params.push({key: "k_test", value: "1" })
            params.push({key: "k_ft1", value: "64" })
            $.each(params, function (i, entry) {
                baseUrl += "&" + entry.key + "=" + entry.value;
            })
            return baseUrl;
        },

        doVRSFreeQueryFirst: function (callback) {
            var queryUrl = Stream.Util.buildVRSFreeUrl(Stream.Config.CHANNEL_INFO.qipuId, Stream.Config.VRS_CONFIG.S_SRC_13);
            var options = {
                url: queryUrl,
                type: 'get',
                dataType: "json",
                timeout:2000,
                success: function (data) {
                    if (data == null || "A00000" != data.code) {
                        console.log("vrs 第一次请求失败:" + JSON.stringify(data));
                        Stream.Util.doVRSFreeQuerySecond(callback);
                    } else {
                        Stream.Config.VRS_DATA = data.data;
                        callback();
                    }
                },
                error: function (data) {
                    console.log("vrs 第一次请求失败")
                    Stream.Util.doVRSFreeQuerySecond(callback);
                }
            }
            EpgWeb.Dao.sendProxy(options)
        },
        doVRSFreeQuerySecond: function (callback) {
            var queryUrl = Stream.Util.buildVRSFreeUrl(Stream.Config.CHANNEL_INFO.qipuId, Stream.Config.VRS_CONFIG.S_SRC_15);
            var options = {
                url: queryUrl,
                type: 'get',
                dataType: 'json',
                timeout:2000,
                success: function (data) {
                    if (data == null || "A00000" != data.code) {
                        console.log("vrs 第二次请求失败:" + JSON.stringify(data))
                    } else {
                        Stream.Config.VRS_DATA = data.data;
                    }
                    callback();
                },
                error: function (data) {
                    console.log("vrs 第二次请求失败");
                    callback();
                }
            }
            EpgWeb.Dao.sendProxy(options)
        },
        buildVRSVipUrl: function (qipuId) {
            return Stream.Config.VRS_CONFIG.BASE_VIP_URL + "?lc=" + qipuId;
        },
        doVRSVipQuery: function (callback) {
            if (auth.dev()) {
                console.log(" disbale in dev mode ");
                callback();
                return ;
            }

            var getQueryUrl = Stream.Util.buildVRSVipUrl(Stream.Config.CHANNEL_INFO.qipuId);
            $.ajax(getQueryUrl, {
                timeout:2000,
                //      $.ajax("http://port.qiyi.com/live/vip/ts?lc=380309622",{
                success: function (data) {
                    if(typeof data == "string" && data.startsWith("http")){
                        console.log(" doVRSVipQuery suc:" + data);
                        Stream.Util.doVRSVipDataQuery(data.substring(0, data.lastIndexOf("&")), function () {
                            callback();
                        })
                    }else{
                        console.log("doVRSVipQuery fail:" +JSON.stringify(data) )
                        callback();
                    }
                },
                error: function (data) {
                    console.log("fail:" + data);
                    callback();
                }
            })
        },
        doVRSVipDataQuery: function (queryUrl, handler) {
            var options = {
                url: queryUrl,
                type: "get",
                dataType:"json",
                success: function (data) {
                    if (data != null && data.code == "A00000") {
                        Stream.Config.VRS_DATA = data.data;
                    } else {
                        console.log("doVRSVipDataQuery fail:" + JSON.stringify(data));
                    }
                    handler();
                },
                error: function (data) {
                    console.log("doVRSVipDataQuery fail:" + data);
                    handler();
                }
            }
            EpgWeb.Dao.sendProxy(options);
        }

    });

});